
#include "Singleton.h"

// v1
Singleton* Singleton::instance_v_1_ = nullptr;

Singleton* Singleton::get_instance_v1()
{
  if (!instance_v_1_) {
    instance_v_1_ = new Singleton();
  }
  return instance_v_1_;
}

// v2
Sp_Singleton Singleton::instance_v_2_ = nullptr;
std::mutex Singleton::mutex_v_2_;

Sp_Singleton Singleton::get_instance_v2()
{
  if (!instance_v_2_) {
    std::lock_guard<std::mutex> lock(mutex_v_2_); // 加锁
    if (!instance_v_2_) {
      instance_v_2_ = std::shared_ptr<Singleton>(new Singleton());
    }
  }
  return instance_v_2_;
}

// v3
std::atomic<Singleton*> Singleton::instance_v_3_;
std::mutex Singleton::mutex_v_3_;

Singleton* Singleton::get_instance_v3()
{
  Singleton* t = instance_v_3_.load(std::memory_order_relaxed);
  std::atomic_thread_fence(std::memory_order_acquire);
  if (!t) {
    // 加锁
    std::lock_guard<std::mutex> lock(mutex_v_3_);
    t = instance_v_3_.load(std::memory_order_relaxed);
    if (!t) {
      t = new Singleton();
      std::atomic_thread_fence(std::memory_order_release);
      instance_v_3_.store(t, std::memory_order_relaxed);
    }
  }
  return t;
}

// v4
Singleton* Singleton::get_instance_v4()
{
  static Singleton instance;
  return &instance;
}
